﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Net;
using System.Xml;
using System.Data.Entity;
using System.IO;
using CloudObserverDB;

namespace CloudObserverAgent
{
	public class CloudObserverLogic
	{
		public void Observe(string query, int noCams, int duration)
		{
			System.Diagnostics.EventLog.WriteEntry("CloudObserver", "Starting observations");
			string url = "http://api.wunderground.com/auto/wui/geo/GeoLookupXML/index.xml?query=" + query;

			// Create an interface to the web
			WebClient c = new WebClient();
			// Download the XML into a string
			string xml = string.Empty;
			bool retry = true;
			int retryCount = 0;
			while (retry)
			{
				try
				{
					xml = ASCIIEncoding.Default.GetString(c.DownloadData(url));
					retry = false;
				}
				catch
				{
					System.Threading.Thread.Sleep(5000);
					retry = true;
					retryCount++;

					if (retryCount > 5) throw new Exception("API not reachable");
				}
			}

			// Document to contain the feed
			XmlDocument doc = new XmlDocument();
			// Parse the xml
			doc.LoadXml(xml);

			using (var db = new CloudObserverDB.CloudObservationContext())
			{
				// db.Database.Delete();

				DateTime startTime = System.DateTime.Now;

				while (true)
				{
					System.Diagnostics.EventLog.WriteEntry("CloudObserver", "In observation loop.");

					int nodeCount = 0;
					foreach (XmlNode node in doc.SelectNodes("/location/webcams/cam"))
					{
						nodeCount++;
						try
						{
							CloudObservation o = new CloudObservation
							{
								Query = query,
								CloudObservationId = Guid.NewGuid().ToString(),
								CameraId = node.SelectSingleNode("camid").InnerText,
								City = node.SelectSingleNode("city").InnerText,
								Frequency = int.Parse(node.SelectSingleNode("frequency").InnerText),
								ImageUrl = node.SelectSingleNode("CURRENTIMAGEURL").InnerText,
								Lat = node.SelectSingleNode("lat").InnerText,
								Long = node.SelectSingleNode("lon").InnerText,
								ImageTimeStamp = DateTime.Parse(node.SelectSingleNode("updated").InnerText),
								ObservationTimeStamp = DateTime.Now
							};

							WebRequest req = WebRequest.Create(o.ImageUrl);
							WebResponse response = req.GetResponse();
							Stream stream = response.GetResponseStream();

							o.Image = ReadFully(stream);

							System.Diagnostics.EventLog.WriteEntry("CloudObserver", "Adding " + o.CameraId);
							db.CloudObservations.Add(o);

							if (nodeCount > noCams) break;
						}
						catch (Exception ex)
						{
							System.Diagnostics.EventLog.WriteEntry("CloudObserver", ex.Message + ": ");
							throw ex;
						}
					}

					try
					{
						db.SaveChanges();
					}
					catch (Exception ex)
					{
						System.Diagnostics.EventLog.WriteEntry("CloudObserver", "Database save failed. " + ex.Message);
					}
					System.Diagnostics.EventLog.WriteEntry("CloudObserver", "Database saved.");

					System.Threading.Thread.Sleep(new TimeSpan(0, 0, 5, 0, 0));
					TimeSpan span = System.DateTime.Now.Subtract(startTime);

					if (span.Minutes > duration) break;
				}


			}

			//<cam> <handle>hoevenm</handle> <camid>hoevenmCAM1</camid> <camindex>1</camindex> <type>ftp</type>
			//<assoc_station_id>IFLEVOLA1</assoc_station_id> <link>http://www.weerinlelystad.nl/lelycam.jpg</link> 
			//<linktext>Lelystad Netherlands Webcam</linktext> <cameratype>IP webcam</cameratype> <organization/> 
			//<neighborhood/> <zip>8226NC</zip> <city>Lelystad</city> <state>FLEVOLAND</state> <country>Netherlands</country>
			//<tzname>Europe/Amsterdam</tzname> <hexant>1</hexant> <hexid>13865</hexid> <lat>52.48795700</lat> <lon>5.49889421</lon>
			//<updated>2011-06-09 09:10:45</updated> <downloaded>0000-00-00 00:00:00</downloaded>
			//<hash>cf5888a5e9f69cae73b710fefda2889ae3f193d2</hash> <isrecent>1</isrecent> <frequency>300</frequency> 
			//<CURRENTIMAGEURL>http://icons.wunderground.com/webcamramdisk/h/o/hoevenm/1/current.jpg?t=1307625127</CURRENTIMAGEURL> 
			//<WIDGETCURRENTIMAGEURL>http://icons.wunderground.com/webcamramdisk/h/o/hoevenm/1/widget.jpg?t=1307625127</WIDGETCURRENTIMAGEURL> 
			//<CAMURL>http://www.wunderground.com/webcams/hoevenm/1/show.html</CAMURL> </cam>
		}

		public static byte[] ReadFully(Stream input)
		{
			byte[] buffer = new byte[16 * 1024];
			using (MemoryStream ms = new MemoryStream())
			{
				int read; while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
				{ ms.Write(buffer, 0, read); } return ms.ToArray();
			}
		}

		public ICollection<CloudObservation> GetObservations(int query, int count)
		{
			List<CloudObservation> list = new List<CloudObservation>();
			return list;
		}
	}
}
